package com.myjob.controller;

import com.myjob.entity.Blog;
import com.myjob.enums.RedisEnums;
import com.myjob.response.Result;
import com.myjob.service.BlogService;
import com.myjob.utils.RedisUtil;
import com.myjob.utils.UtilValidate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author Chen Yuan
 * @create 2021-02-28  16:01
 */
@RestController
@Slf4j
@RequestMapping("/blog")
@EnableScheduling   //开启定时任务
public class BlogRedisController {
	@Autowired
	private RedisUtil redisUtil;
	@Autowired
	private BlogService blogService;

	@GetMapping("/updateReadNumber/{blogId}")
	public void updateReadNumber(@PathVariable("blogId") Long blogId){
		String key = RedisEnums.KEY_IN_REDIS.READ_NUM.getValue();
		// 从 Redis 读取数据
		Map<String, Integer> blogReadNumbers = (Map<String, Integer>) redisUtil.get(key);
		// 如果读到的为空，则新建一个 Map
		if (UtilValidate.isEmpty(blogReadNumbers)) {
			blogReadNumbers = new HashMap<>();
		}
		// Get 博客编号对应的阅读量
		Integer integer = blogReadNumbers.get(String.valueOf(blogId));
		// 如果阅读量为空，即博客不在 Map 中
		if (UtilValidate.isEmpty(integer)) {
			Result result = blogService.selectBlogById(blogId);
			Blog blog = (Blog) result.getDatas();
			integer = blog.getReadNumber();
		}
		// 阅读量 +1，存入 Redis
		int i = integer + 1;
		blogReadNumbers.put(String.valueOf(blogId), i);
		redisUtil.set(key, blogReadNumbers, 15, TimeUnit.SECONDS);
		log.info("<< Redis >> - 将 blogId="+blogId+" 博客阅读量变为: "+i+" ,并存入 Redis, 过期时间 20s");
	}

	@Scheduled(cron = "0/10 * * * * ?")
	public void setNumberToRedis(){
		log.info("<< Redis >> - 开始将 Redis 中所有的博客阅读量存入数据库");

		// 获取所有的阅读量信息
		Map<String, Integer> map = (Map<String, Integer>) redisUtil.get(RedisEnums.KEY_IN_REDIS.READ_NUM.getValue());

		if (UtilValidate.isEmpty(map)) {
			// 如果 阅读量Map 为空直接返回，后面不需要执行了
			return;
		}
		// 创建 Blog 列表，后面直接批量修改
		ArrayList<Blog> blogs = new ArrayList<>();
		// 利用迭代器进行 Map 遍历
		Set<String> keySet = map.keySet();
		Iterator<String> iterator = keySet.iterator();
		while (iterator.hasNext()) {
			Blog blog = new Blog();
			String key = iterator.next();
			blog.setBlogId(key);
			blog.setReadNumber(map.get(key));
			blogs.add(blog);
		}
		blogService.updateBatchById(blogs);
	}
}
